<?php


namespace app\common\cachemodel;


use app\common\lib\SensorsData;
use app\common\lib\Util;
use app\common\model\BaseCache;
use app\common\model\Goods;
use think\Exception;
use think\exception\PDOException;
use XznsTools\cache\CacheManage;

class ZlCouponActive extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zl_coupon_active';

    protected $cacheModel = 'coupon.active';

    public $errorMsg = '';

    public $isGiveOver = true;

    /**
     * 获取活动优惠券信息
     * @return array|bool|mixed
     * @throws \Exception
     */
    public function getActiveInfo()
    {
        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, 'info')->getDataAndSet(function ()
        {
            return $this->getActiveInfoByDb();
        });

        return json_decode($data, true);
    }

    /**
     * 获取活动优惠券信息
     * @return false|string
     */
    private function getActiveInfoByDb()
    {
        try
        {
            $data = $this->alias('a')
                ->join('wechat_backup_07_18_14_43_00.zl_coupon_attr c', 'a.c_id=c.id')
                ->where('a.status', 1)
                ->column('a.c_id,a.name,a.start_time,a.end_time,a.send_type,a.send_max_num,a.send_num,a.send_mode,a.c_num,a.expire_type,a.expire_day,a.expire_time,a.ur_id,a.is_give,c.type,c.rand_min,c.rand_max,c.desc,c.gids', 'a.id');
        }
        catch (Exception $e)
        {
            $data = [];
        }

        return json_encode($data);
    }

    /**
     * 领取活动优惠券
     * @param int $uid
     * @return bool
     * @throws PDOException
     * @throws \Exception
     */
    public function couponGive(int $uid)
    {
        $couponData = $this->getActiveInfo();

        $couponActiveGiveRecordModel = new ZlCouponActiveGiveRecord();
        $giveRecordData = $couponActiveGiveRecordModel->getGiveRecord($uid);
        $giveRecordDataIds = empty($giveRecordData) ? [] : array_keys($giveRecordData);
        $time = time();
        $userCouponModel = new UserCoupon();
        $ids = [];  // 未使用优惠券ID
        $giveIds = [];// 可赠与优惠券ID
        $giveRecodeIds = [];
        $giveRecodeData = [];
        $activeIds = [];// 领取的优惠券 活动ID
        $this->startTrans();
        try
        {
            foreach ($couponData as $couponItem)
            {
                if (!in_array($couponItem['id'], $giveRecordDataIds) && $couponItem['start_time'] < $time && $time < $couponItem['end_time'])
                {   // 领取可领取的优惠券 没用领取过 且 在领取时间之内
                    if ($couponItem['send_type'] == 2 && $couponItem['send_max_num'] <= $couponItem['send_num'])
                    {   // 超过领取上线
                        continue;
                    }
                    for ($i = 0; $i < $couponItem['c_num']; $i++)
                    {
                        if ($couponItem['expire_type'] == 1)
                        {   // 固定到期时间
                            $endTime = $couponItem['expire_time'];
                        } else
                        {   // 固定过期天数
                            $endTime = $couponItem['expire_day'] !== 0 ? strtotime("+{$couponItem['expire_day']} day") : 0;
                        }
                        $cData = [
                            'uid' => $uid,
                            'c_id' => $couponItem['c_id'],
                            'ur_id' => $couponItem['ur_id'],
                            'start_time' => $time,
                            'end_time' => $endTime,
                            'give_time' => $time,
                            'status' => 0,
                            'price' => $couponItem['type'] == 4 ? mt_rand($couponItem['rand_min'], $couponItem['rand_max']) : 0,
                            'is_give' => $couponItem['is_give'],
                            'create_time' => $time,
                            'update_time' => $time,
                        ];
                        $ucId = $userCouponModel->insertGetId($cData);
                        $ids[$ucId] = $ucId; // 添加未用于ID
                        if ($couponItem['is_give'] == 1)
                        {
                            $giveIds[$ucId] = $ucId;
                        }
                    }
                    $activeIds[] = $couponItem['id'];
                    $giveRecodeData[] = [
                        'uid' => $uid,
                        'ca_id' => $couponItem['id'],
                        'create_time' => $time
                    ];
                    $giveRecodeIds[$couponItem['id']] = $time;
                }
            }
            if ($giveRecodeData)
            {
                $couponActiveGiveRecordModel->saveAll($giveRecodeData);
            }
            $this->commit();
        }
        catch (Exception $e)
        {
            $this->rollback();
            $this->errorMsg = '服务异常';
            return false;
        }

        if ($ids)
        {
            $userCouponModel->listDataAdd($uid, $ids, 1);
            if ($giveIds)
            {   // 可赠与
                $userCouponModel->listDataAdd($uid, $giveIds, 2);
            }
            if ($giveRecodeIds)
            {
                $couponActiveGiveRecordModel->cacheAddRecord($uid, $giveRecodeIds);
            }
            if ($activeIds)
            {   // 更新已经领取数量领取
                foreach ($couponData as $key => $couponItem)
                {
                    if (in_array($couponItem['id'], $activeIds, true))
                    {
                        $this->where('id', $couponItem['id'])->setInc('send_num', $couponItem['c_num']);
                        $couponData[$key]['send_num'] += $couponItem['c_num'];
                    }
                }
            }
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, 'info')->setCache($couponData);
            return true;
        } else
        {
            $this->errorMsg = '无可领取卷';
            return false;
        }
    }

    /**
     * 领取春节指定活动优惠券 一次性全领
     * @param int $uid
     * @param int $activId 优惠券活动ID
     * @return bool
     * @throws Exception
     * @throws PDOException
     * @throws \Exception
     */
    public function couponGiveActiv(int $uid, $activId = 0)
    {
        $couponData = $this->getActiveInfo();

        $couponActiveGiveRecordModel = new ZlCouponActiveGiveRecord();
        $giveRecordData = $couponActiveGiveRecordModel->getGiveRecord($uid);
        $giveRecordDataIds = empty($giveRecordData) ? [] : array_keys($giveRecordData);
        if (in_array($activId, $giveRecordDataIds))
        {
            $this->errorMsg = '优惠券已领取过了';
            return false;
        }
        $time = Util::testGetTime();

        $userCouponModel = new UserCoupon();
        $ids = [];  // 未使用优惠券ID
        $giveIds = [];// 可赠与优惠券ID
        $giveRecodeIds = [];
        $giveRecodeData = [];
        $activeIds = [];// 领取的优惠券 活动ID
        $this->startTrans();
        try
        {
            foreach ($couponData as $couponItem)
            {
                if ($activId == $couponItem['id'])
                {   // 领取可领取的优惠券 没用领取过 且 在领取时间之内

                    if ($couponItem['start_time'] > $time)
                    {
                        $this->errorMsg = '活动未开始';
                        return false;
                    }
                    if ($time > $couponItem['end_time'])
                    {
                        $this->errorMsg = '活动已结束';
                        return false;
                    }

                    if ($couponItem['send_type'] == 2 && $couponItem['send_max_num'] <= $couponItem['send_num'])
                    {   // 超过领取上线
                        $this->errorMsg = '优惠券已空；领取失败';
                        return false;
                    }
                    for ($i = 0; $i < $couponItem['c_num']; $i++)
                    {
                        if ($couponItem['expire_type'] == 1)
                        {   // 固定到期时间
                            $endTime = $couponItem['expire_time'];
                        } else
                        {   // 固定过期天数
                            $endTime = $couponItem['expire_day'] !== 0 ? strtotime("+{$couponItem['expire_day']} day") : 0;
                        }
                        $cData = [
                            'uid' => $uid,
                            'c_id' => $couponItem['c_id'],
                            'ur_id' => $couponItem['ur_id'],
                            'start_time' => $time,
                            'end_time' => $endTime,
                            'give_time' => $time,
                            'status' => 0,
                            'price' => $couponItem['type'] == 4 ? mt_rand($couponItem['rand_min'], $couponItem['rand_max']) : 0,
                            'is_give' => $couponItem['is_give'],
                            'create_time' => $time,
                            'update_time' => $time,
                        ];
                        $ucId = $userCouponModel->insertGetId($cData);
                        $ids[$ucId] = $ucId; // 添加未用于ID
                        if ($couponItem['is_give'] == 1)
                        {
                            $giveIds[$ucId] = $ucId;
                        }
                        $couponTypeName = [1 => '折扣', 2 => '立减', 3 => '满减', 4 => '随机', 5 => '免费'];
                        $couponRangeArr = (new Goods())->where('id', 'in', $couponItem['gids'])->column('name');
                        // 神策打点 75 获得优惠券 AcquireCoupon
                        SensorsData::track($uid, true, 'AcquireCoupon', [
                            'refer_name' => '手动领取',
                            'refer_link' => 'zhunle_api',
                            'coupon_name' => $couponItem['desc'],
                            'coupon_expire' => date('Y-m-d H:i:s', $cData['end_time']),
                            'coupon_type' => $couponTypeName[$couponItem['type']],
                            'coupon_range' => $couponRangeArr,
                            'acquire_channel' => $couponItem['name'],
                            'is_give' => false,
                            'acquire_scene' => '活动H5',
                        ]);
                    }
                    $activeIds[] = $couponItem['id'];
                    $giveRecodeData[] = [
                        'uid' => $uid,
                        'ca_id' => $couponItem['id'],
                        'create_time' => $time
                    ];
                    $giveRecodeIds[$couponItem['id']] = $time;
                }
            }
            if ($giveRecodeData)
            {
                $couponActiveGiveRecordModel->saveAll($giveRecodeData);
            }
            $this->commit();
        }
        catch (Exception $e)
        {
            $this->rollback();
            $this->errorMsg = '服务异常';
            return false;
        }

        if ($ids)
        {
            $userCouponModel->listDataAdd($uid, $ids, 1);
            if ($giveIds)
            {   // 可赠与
                $userCouponModel->listDataAdd($uid, $giveIds, 2);
            }
            if ($giveRecodeIds)
            {
                $couponActiveGiveRecordModel->cacheAddRecord($uid, $giveRecodeIds);
            }
            if ($activeIds)
            {   // 更新已经领取数量领取
                foreach ($couponData as $key => $couponItem)
                {
                    if (in_array($couponItem['id'], $activeIds, true))
                    {
                        $this->where('id', $couponItem['id'])->setInc('send_num', $couponItem['c_num']);
                        $couponData[$key]['send_num'] += $couponItem['c_num'];
                    }
                }
            }
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, 'info')->setCache($couponData);
            return true;
        } else
        {
            $this->errorMsg = '优惠券已空；领取失败';
            return false;
        }
    }

    /**
     * 领取春节指定活动优惠券 可多次领取
     * @param int $year
     * @param int $uid
     * @param int $activId 优惠券活动ID
     * @return bool
     * @throws Exception
     * @throws PDOException
     * @throws \Exception
     */
    public function couponActivMoreGive(int $year, int $uid, int $activId = 0): bool
    {
        $couponData = $this->getActiveInfo();

        $couponActiveGiveRecordModel = new ZlCouponActiveGiveRecord();
        $giveNum = $couponActiveGiveRecordModel->getActiveGiveNum($uid, $activId);

        $time = Util::testGetTime((string)$year);

        $userCouponModel = new UserCoupon();
        $ids = [];  // 未使用优惠券ID
        $giveIds = [];// 可赠与优惠券ID
        $giveRecodeIds = [];
        $giveRecodeData = [];
        $activeIds = [];// 领取的优惠券 活动ID
        $this->startTrans();
        try
        {
            $couponItem = $couponData[$activId] ?? null;    // 获取领取指定活动优惠券
            if ($couponItem && $activId === (int)$couponItem['id'])
            {   // 当前活动存在
                // 判断用户可领取数量未达上线 且 在领取时间之内
                if ($giveNum >= $couponItem['c_num'])
                {
                    $this->errorMsg = '优惠券单人领取已达上限</div><div class="msg-item">领取失败';
                    return false;
                }

                if ($couponItem['start_time'] > $time)
                {
                    $this->errorMsg = '活动未开始';
                    return false;
                }
                if ($time > $couponItem['end_time'])
                {
                    $this->errorMsg = '活动已结束';
                    return false;
                }

                if ((int)$couponItem['send_type'] === 2 && $couponItem['send_max_num'] <= $couponItem['send_num'])
                {   // 超过领取上线
                    $this->errorMsg = '哎呀、已经抢没了～';
                    return false;
                }

                if ((int)$couponItem['expire_type'] === 1)
                {   // 固定到期时间
                    $endTime = $couponItem['expire_time'];
                } else
                {   // 固定过期天数
                    $endTime = $couponItem['expire_day'] !== 0 ? strtotime("+{$couponItem['expire_day']} day") : 0;
                }
                $cData = [
                    'uid' => $uid,
                    'c_id' => $couponItem['c_id'],
                    'ur_id' => $couponItem['ur_id'],
                    'start_time' => $time,
                    'end_time' => $endTime,
                    'give_time' => $time,
                    'status' => 0,
                    'price' => (int)$couponItem['type'] === 4 ? random_int($couponItem['rand_min'], $couponItem['rand_max']) : 0,
                    'is_give' => $couponItem['is_give'],
                    'create_time' => $time,
                    'update_time' => $time,
                ];
                $ucId = $userCouponModel->insertGetId($cData);
                $ids[$ucId] = $ucId; // 添加未用于ID
                if ((int)$couponItem['is_give'] === 1)
                {
                    $giveIds[$ucId] = $ucId;
                }

                $activeIds[] = $couponItem['id'];
                $giveRecodeData[] = [
                    'uid' => $uid,
                    'ca_id' => $couponItem['id'],
                    'create_time' => $time
                ];
                $giveRecodeIds[$couponItem['id']] = $time;
            }

            if ($giveRecodeData)
            {
                $couponActiveGiveRecordModel->saveAll($giveRecodeData);
            }
            $this->commit();
        }
        catch (Exception $e)
        {
            $this->rollback();
            $this->errorMsg = '服务异常';
            return false;
        }

        if ($ids)
        {
            $userCouponModel->listDataAdd($uid, $ids, 1);
            if ($giveIds)
            {   // 可赠与
                $userCouponModel->listDataAdd($uid, $giveIds, 2);
            }
            if ($giveRecodeIds)
            {
                $couponActiveGiveRecordModel->cacheAddRecord($uid, $giveRecodeIds); // 添加活动参与记录
                $couponActiveGiveRecordModel->activeGiveNumInc($uid, $activId);  // 增加优惠券领取数量
            }

            if ($activeIds)
            {   // 更新已经领取数量领取
                foreach ($couponData as $key => $couponItem)
                {
                    if (in_array($couponItem['id'], $activeIds, true))
                    {
                        $this->where('id', $couponItem['id'])->setInc('send_num', 1);
                        $couponData[$key]['send_num'] += 1;
                    }
                }
            }

            CacheManage::getInstance()->setCacheConfig($this->cacheModel, 'info')->setCache($couponData);
            if ($giveNum + 1 < $couponItem['c_num'])
            {   // 当领取数量未达上线时 没有领取结束 还可以再领取
                $this->isGiveOver = false;
            }

            return true;
        }

        $this->errorMsg = '优惠券已空；领取失败';
        return false;
    }
}
